package com.uinnova.product.eam.service.counter.impl;

import com.binary.jdbc.Page;
import com.uinnova.product.eam.base.domain.CounterTypeEnum;
import com.uinnova.product.eam.comm.model.es.EamOpCounter;
import com.uinnova.product.eam.service.counter.IEamOpCountSvc;
import com.uinnova.product.eam.service.es.IamsEamESOpCounterDao;
import com.uino.dao.util.ESUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class EamOpCountSvcImpl implements IEamOpCountSvc {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private IamsEamESOpCounterDao iamsEamESOpCounterDao;


    @Override
    public Long insert(String ciCode, CounterTypeEnum counterType, Long domainId, Long times) {
        EamOpCounter record = new EamOpCounter();
        record.setId(ESUtil.getUUID());
        record.setCiCode(ciCode);
        record.setCounterType(counterType.name());
        record.setTimes(times);
        record.setCreateTime(System.currentTimeMillis());
        record.setDomainId(domainId);
        return iamsEamESOpCounterDao.saveOrUpdate(record);
    }

    @Override
    public boolean increaseCount(String ciCode, CounterTypeEnum counterType, Long domainId) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("ciCode.keyword", ciCode));
        boolQuery.must(QueryBuilders.termQuery("counterType.keyword", counterType.name()));
        boolQuery.must(QueryBuilders.termQuery("domainId", domainId));
        long num = iamsEamESOpCounterDao.countByCondition(boolQuery);
        if(num > 0){
            String script = "ctx._source.times+=1;";
            iamsEamESOpCounterDao.updateByQuery(boolQuery, script, true);
        }else {
            insert(ciCode, counterType, domainId, 1L);
        }
        if(counterType == CounterTypeEnum.SPECIFICATION){
            insert(ciCode, CounterTypeEnum.SPECIFICATION_LOG, domainId, 1L);
        }
        return true;
    }

    @Override
    public Map<String, Long> selectCounterMap(List<String> ciCodes) {
        if(CollectionUtils.isEmpty(ciCodes)){
            return Collections.emptyMap();
        }
        BoolQueryBuilder boolQuery =  QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termsQuery("ciCode.keyword", ciCodes));
        boolQuery.must(QueryBuilders.termQuery("counterType.keyword", CounterTypeEnum.SPECIFICATION.name()));
        List<EamOpCounter> list = iamsEamESOpCounterDao.getListByQuery(boolQuery);
        if(CollectionUtils.isEmpty(ciCodes)){
            return Collections.emptyMap();
        }
        return list.stream().collect(Collectors.toMap(EamOpCounter::getCiCode,EamOpCounter::getTimes, (key1, key2) -> key2));
    }

    @Override
    public List<EamOpCounter> selectTopList(int topNum, CounterTypeEnum counterType, Set<String> ciCodes){
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery("counterType.keyword", counterType.name()));
        queryBuilder.must(QueryBuilders.termsQuery("ciCode.keyword", ciCodes));
        queryBuilder.must(QueryBuilders.rangeQuery("times").gt(0));
        Page<EamOpCounter> page = iamsEamESOpCounterDao.getSortListByQuery(1, topNum, queryBuilder, "times", false);
        return page.getData();
    }

    @Override
    public long countRecords(CounterTypeEnum counterType, long endTime) {
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery("counterType.keyword", counterType.name()));
        queryBuilder.must(QueryBuilders.rangeQuery("createTime").gt(endTime));
        return iamsEamESOpCounterDao.countByCondition(queryBuilder);
    }
}
